module tend_mod

  use spark_cubed_sphere
  use params_mod
  
  implicit none

  private
  
  public tend_type
  public tend
  public tend_IRK
  public tend_IM
  public tend_EX
  public tend_HON

  type tend_panel_array_type
    ! 1: x-axis
    ! 2: y-axis
    ! 3: z-axis
    ! 4: variable
    !                            1 2 3 4
    real(r8), pointer, dimension(:,:,:,:) :: q
  end type tend_panel_array_type
  
  type tend_type
    logical :: initialized = .false.
    type(cubed_sphere_mesh_type), pointer :: mesh => null()
    type(cubed_sphere_array_type) array
    type(tend_panel_array_type) domain(6)
  contains
    procedure :: init  => tend_init
    procedure :: clear => tend_clear
    final :: tend_final
  end type tend_type
  
  type(tend_type ), allocatable :: tend (:)
  type(tend_type )              :: tend_IRK
  type(tend_type ), allocatable :: tend_IM(:)
  type(tend_type ), allocatable :: tend_EX(:)
  type(tend_type ), allocatable :: tend_HON(:) ! tend for High Order Newton method

contains

  subroutine tend_init(this, mesh)

    class(tend_type), intent(inout) :: this
    type(cubed_sphere_mesh_type), intent(in), target :: mesh

    integer idom

    call this%clear()

    this%mesh => mesh
    call this%array%init(mesh)

    if(model_type==0)then
        
      call this%array%add_var('dq1dt', &
        dtype='r8', &
        long_name='Tendency of q1', &
        units='-', &
        loc='CA', &
        with_halo='T', &
        fill_halo='F', &
        tag='dqdt', &
        output='F')
      
    elseif(model_type==1)then
        
      call this%array%add_var('dq1dt', &
        dtype='r8', &
        long_name='Tendency of q1', &
        units='-', &
        loc='CA', &
        with_halo='T', &
        fill_halo='F', &
        tag='dqdt', &
        output='F')
      
      call this%array%add_var('dq2dt', &
        dtype='r8', &
        long_name='Tendency of q2', &
        units='-', &
        loc='CA', &
        with_halo='T', &
        fill_halo='F', &
        tag='dqdt', &
        output='F')
      
      call this%array%add_var('dq3dt', &
        dtype='r8', &
        long_name='Tendency of q3', &
        units='-', &
        loc='CA', &
        with_halo='T', &
        fill_halo='F', &
        tag='dqdt', &
        output='F')
      
    elseif(model_type==2)then
        
      call this%array%add_var('dq1dt', &
        dtype='r8', &
        long_name='Tendency of q1', &
        units='-', &
        loc='CA', &
        with_halo='T', &
        fill_halo='F', &
        tag='dqdt', &
        output='F')
      
      call this%array%add_var('dq2dt', &
        dtype='r8', &
        long_name='Tendency of q2', &
        units='-', &
        loc='CA', &
        with_halo='T', &
        fill_halo='F', &
        tag='dqdt', &
        output='F')
      
      call this%array%add_var('dq3dt', &
        dtype='r8', &
        long_name='Tendency of q3', &
        units='-', &
        loc='CA', &
        with_halo='T', &
        fill_halo='F', &
        tag='dqdt', &
        output='F')
      
      call this%array%add_var('dq4dt', &
        dtype='r8', &
        long_name='Tendency of q4', &
        units='-', &
        loc='CA', &
        with_halo='T', &
        fill_halo='F', &
        tag='dqdt', &
        output='F')
      
      call this%array%add_var('dq5dt', &
        dtype='r8', &
        long_name='Tendency of q5', &
        units='-', &
        loc='CA', &
        with_halo='T', &
        fill_halo='F', &
        tag='dqdt', &
        output='F')
      
      call this%array%add_var('dq6dt', &
        dtype='r8', &
        long_name='Tendency of q6', &
        units='-', &
        loc='CA', &
        with_halo='T', &
        fill_halo='F', &
        tag='dqdt', &
        output='F')
      
    endif
    
    call this%array%allocate_arrays()

    do idom = 1, mesh%ndom
      if (mesh%domain(idom)%initialized) then
        call this%array%get_array(this%domain(idom)%q, idom=idom, loc='CA', tag='dqdt')
      end if
    end do

    this%initialized = .true.

  end subroutine tend_init

  subroutine tend_clear(this)

    class(tend_type), intent(inout) :: this

    call this%array%clear()

    this%initialized = .false.

  end subroutine tend_clear

  subroutine tend_final(this)

    type(tend_type), intent(inout) :: this

    call this%clear()

  end subroutine tend_final

end module tend_mod
